package com.ypf.rpc.registery;

import com.ypf.rpc.message.RpcRegisterRequestMessage;
import com.ypf.rpc.nettyHandler.RegisterHeartBeatClientHandler;
import com.ypf.rpc.nettyHandler.RegisterHeartBeatServerHandler;
import com.ypf.rpc.procotol.MessageCodecSharable;
import com.ypf.rpc.procotol.ProcotolFrameDecoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
public class ServerRegistryImpl implements ServerRegistry{

    /**
     * 开启一个socket通道与注册中心保持联系
     * @param serviceNameList
     * @param inetSocketAddress
     */
    @Override
    public void register(List<String> serviceNameList, InetSocketAddress inetSocketAddress) {
        // 日志handler
        LoggingHandler LOGGING_HANDLER = new LoggingHandler(LogLevel.DEBUG);

        // 消息处理handler
        MessageCodecSharable MESSAGE_CODE = new MessageCodecSharable();

        // 自定义向注册中心 发送心跳处理器
        RegisterHeartBeatClientHandler REGISTER_HEARTBEAT_CLIENT = new RegisterHeartBeatClientHandler();

        NioEventLoopGroup group = new NioEventLoopGroup();

        try {
            ChannelFuture channelFuture = new Bootstrap().group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            // 定长解码器
                            socketChannel.pipeline().addLast(new IdleStateHandler(0,5,0, TimeUnit.SECONDS));
                            socketChannel.pipeline().addLast(new ProcotolFrameDecoder());
                            socketChannel.pipeline().addLast(MESSAGE_CODE);
                            socketChannel.pipeline().addLast(REGISTER_HEARTBEAT_CLIENT);

                        }
                    }).connect(new InetSocketAddress("127.0.0.1",10001)).sync();
            Channel channel = channelFuture.channel();

            // 将 ArrayList 转换为字符串数组。
            String[] serviceNames = new String[serviceNameList.size()];
            for (int i = 0; i < serviceNameList.size(); i++) {
                serviceNames[i] = serviceNameList.get(i);
            }

            RpcRegisterRequestMessage rpcRegisterRequestMessage = new RpcRegisterRequestMessage(serviceNames,inetSocketAddress.getHostName(),inetSocketAddress.getPort());
            channel.writeAndFlush(rpcRegisterRequestMessage);

//            channel.closeFuture().sync();  // 同步等待阻塞 此线程将会在这阻塞
            channel.closeFuture().addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    group.shutdownGracefully();
                    log.debug("服务器向注册中心通信channel被关闭...");
                }
            });
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
